﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Utils.MathUtilitys;

namespace Utils.Misc
{
    public class RndFair
    {
        int from;
        int to;
        int length;
        int sequenceBase;
        int[] sequence;
        int current;

        public RndFair(int to)
            : this(0, to, 1) { }

        public RndFair(RangeValue<int> range)
            : this(range.Min, range.Max, 1) { }

        public RndFair(int from, int to)
            : this(from, to, 1) { }

        public RndFair(int from, int to, int sequenceBase)
        {
            Debug.Assert(from <= to, "RndFair Sequence 'from' not <= 'to'");

            this.from = from;
            this.to = to;
            this.sequenceBase = sequenceBase;

            length = (to - from + 1) * sequenceBase;
            sequence = new int[length];

            RestartSequence();
        }

        public int Get()
        {
            if (current >= length)
            {
                RestartSequence();
            }

            return sequence[current++];
        }

        void RestartSequence()
        {
            current = 0;

            for (int i = 0; i < length; i++)
            {
                sequence[i] = from - 1;
            }

            for (int i = 0; i < length; i++)
            {
                bool gapFound = false;

                while (!gapFound)
                {
                    int pos = RndUtils.RndInRange(0, length - 1);

                    if (sequence[pos] < from)
                    {
                        sequence[pos] = from + i % (to - from + 1);
                        gapFound = true;
                    }
                }
            }
        }
    }
}
